#include "kkgui_base.h"

/* =============================== */
/* define */



/* =============================== */
/* typedef */



/* =============================== */
/* variable statement*/
extern uint8_t (*KKUI_Gram_Addr[2])[8];
extern volatile uint8_t oled_gram_page;
extern int KKUI_Gram_Len;
extern int KKUI_Gram_Wide;


extern const unsigned char ui_asc2_0806[][6];
extern const unsigned char ui_asc2_1206[][12];
extern const unsigned char ui_asc2_1608[][16];
extern const unsigned char ui_asc2_2412[][36];

/* =============================== */
/* variable definition*/



/* =============================== */
/* function statement*/


/* =============================== */
/* function definition*/

static int win_x1 = 0, win_y1 = 0, win_x2 = DIS_WIDE, win_y2 = DIS_HIGH;

#define _uiSetPoint(__x, __y, __t)                                \
    if (__x >= win_x1 && __y >= win_y1 && __x < win_x2 && __y < win_y2) \
    (__t) ? ((__t == 1) ? KKUI_Gram_Addr[oled_gram_page][__x][__y / 8] |= 1 << (__y % 8) : (KKUI_Gram_Addr[oled_gram_page][__x][__y / 8] ^= 1 << (__y % 8))) : (KKUI_Gram_Addr[oled_gram_page][__x][__y / 8] &= ~(1 << __y % 8))


// mode：0,全清空， 1，全写
void uiDisClear(uint8_t mode)
{
    uint8_t i, n;
    if (mode)
        mode = 0xff;
    for (i = 0; i < 8; i++)
    {
        for (n = 0; n < 128; n++)
        {
            KKUI_Gram_Addr[oled_gram_page][n][i] = mode; // 清除所有数据
        }
    }
}


void uiSetDisWindows(int x, int y, int w, int h)
{
    if(x < 0) win_x1 = 0;
    else win_x1 = x; 

    if(y < 0) win_y1 = 0;
    else win_y1 = y;

    if(x + w < 0) win_x2 = 0;
    else if(x + w > DIS_WIDE) win_x2 = DIS_WIDE;
    else win_x2 = x + w;

    if(y + h < 0) win_y2 = 0;
    else if(y + h > DIS_HIGH) win_y2 = DIS_HIGH;
    else win_y2 = y + h;
}


void uiClearDisWindows(void)
{
    win_x1 = 0; 
    win_y1 = 0;
    win_x2 = DIS_WIDE;
    win_y2 = DIS_HIGH;
}


// 在指定位置画一个点
// color:0,无色显示;1,正常显示，反色显示
void uiDrawPoint(int x,int y,uint8_t color)
{
    _uiSetPoint(x, y, color);
}


// x,y：起点坐标
// sizex,sizey,图片长宽
// value:蒙版点数
// color:0,无色显示;1,有常显示；2，反色显示
void uiDisMask4Point(int x, int y, int sizex, int sizey, uint8_t value, uint8_t color)
{
    int a, b;
    for (a = x; a < x + sizex; a++)
        for (b = y; b < y + sizey; b++)
        {
            if (value & 0x01)
                if (b % 2 == 0)
                {
                    if (a % 2 == 0)
                    {
                        _uiSetPoint(a, b, color);
                    }
                }
            if (value & 0x02)
                if (b % 2 == 1)
                {
                    if (a % 2 == 0)
                    {
                        _uiSetPoint(a, b, color);
                    }
                }
            if (value & 0x04)
                if (b % 2 == 0)
                {
                    if (a % 2 == 1)
                    {
                        _uiSetPoint(a, b, color);
                    }
                }
            if (value & 0x08)
                if (b % 2 == 1)
                {
                    if (a % 2 == 1)
                    {
                        _uiSetPoint(a, b, color);
                    }
                }
        }
}


// 画横线
void uiDrawHLine(int x,int y,int len, uint8_t color)
{
    uint16_t  ret;
    for(ret = x; ret < x + len ; ret ++)
        _uiSetPoint(ret, y, color);
}

// 画竖线
void uiDrawVLine(int x,int y,int len, uint8_t color)
{
    uint16_t  ret;
    for(ret = y; ret < y + len ; ret ++)
        _uiSetPoint(x, ret, color);
}

// 画线
//x1,y1:起点坐标
//x2,y2:结束坐标
// color:0,无色显示;1,正常显示，反色显示
void uiDrawLine(int x1,int y1,int x2,int y2, uint8_t color)
{
	uint16_t t;
	int xerr=0,yerr=0,delta_x,delta_y,distance;
	int incx,incy,uRow,uCol;
	delta_x=x2-x1; //计算坐标增量
	delta_y=y2-y1;
	uRow=x1;//画线起点坐标
	uCol=y1;
	if(delta_x>0)incx=1; //设置单步方向
	else if (delta_x==0)incx=0;//垂直线
	else {incx=-1;delta_x=-delta_x;}
	if(delta_y>0)incy=1;
	else if (delta_y==0)incy=0;//水平线
	else {incy=-1;delta_y=-delta_x;}
	if(delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
	else distance=delta_y;
	for(t=0;t<distance+1;t++)
	{
		_uiSetPoint(uRow,uCol,color);//画点
		xerr+=delta_x;
		yerr+=delta_y;
		if(xerr>distance)
		{
			xerr-=distance;
			uRow+=incx;
		}
		if(yerr>distance)
		{
			yerr-=distance;
			uCol+=incy;
		}
	}
}

// 在指定位置画一个方块
// x:0~127
// y:0~63
// size1:选择字体 6x8/6x12/8x16/12x24
// color:0,无色显示;1,正常显示，反色显示
void uiDrawBlock(int x, int y, int w, int h, uint8_t color)
{
    int a, b;
    for (a = x; a < x + w; a++)
        for (b = y; b < y + h; b++)
            _uiSetPoint(a, b, color);
}

// 在指定位置画一个方框
// x:0~127
// y:0~63
// size1:选择字体 6x8/6x12/8x16/12x24
// color:0,无色显示;1,正常显示，反色显示
void uiDrawBox(int x, int y, int w, int h, uint8_t color)
{
    uiDrawHLine(x, y, w, color);
    uiDrawHLine(x, y + h - 1, w, color);
    uiDrawVLine(x, y + 1, h - 2, color);
    uiDrawVLine(x + w - 1, y + 1, h - 2, color);
}


void uiDrawDisc(int x0, int y0, uint16_t r, uint8_t option, uint8_t color)
{
	int a, b;
    a = 1;
    b = r;
    _uiSetPoint(x0, y0, color);
    
    if ( option & KKUI_DRAW_UPPER_LEFT ||  option & KKUI_DRAW_UPPER_RIGHT )
        uiDrawVLine(x0, y0-r+1, r-1, color);// 上

    if ( option & KKUI_DRAW_LOWER_LEFT ||  option & KKUI_DRAW_LOWER_RIGHT )
        uiDrawVLine(x0, y0+1, r-1, color);// 下

    if ( option & KKUI_DRAW_UPPER_LEFT ||  option & KKUI_DRAW_LOWER_LEFT )
        uiDrawHLine(x0-r+1, y0, r-1, color);// 左
    
    if ( option & KKUI_DRAW_UPPER_RIGHT ||  option & KKUI_DRAW_LOWER_RIGHT )
        uiDrawHLine(x0+1, y0, r-1, color);// 右
        
    while(b > a)
    {
        b = sqrt(r*r-a*a) + 0.43; // 四舍五入
        if(b - a <= 1 && b >= (int)(sqrt(r*r-(a-1)*(a-1)) + 0.43)) return;
        if(b - a < 1) return;

        if ( option & KKUI_DRAW_UPPER_RIGHT)
        {
            uiDrawVLine(x0+a, y0-b+1, b-a, color);
            uiDrawHLine(x0+a+1, y0-a, b-a-1, color);
        }
        if ( option & KKUI_DRAW_UPPER_LEFT)
        {
            uiDrawVLine(x0-a, y0-b+1, b-a, color);
            uiDrawHLine(x0-b+1, y0-a, b-a-1, color);
        }
        if ( option & KKUI_DRAW_LOWER_RIGHT)
        {
            uiDrawVLine(x0+a, y0+a, b-a, color);
            uiDrawHLine(x0+a+1, y0+a, b-a-1, color);
        }
        if ( option & KKUI_DRAW_LOWER_LEFT)
        {
            uiDrawVLine(x0-a, y0+a, b-a, color);
            uiDrawHLine(x0-b+1, y0+a, b-a-1, color);
        }
        a ++;
    }
}


void uiDrawCircle(int x0, int y0, uint16_t r, uint8_t option, uint8_t color)
{
	int a, b;
    a = 1;
    b = r;
    
    if(r == 1)
        _uiSetPoint(x0, y0, color);
    
    if ( option & KKUI_DRAW_UPPER_LEFT ||  option & KKUI_DRAW_UPPER_RIGHT )
        _uiSetPoint(x0, (y0-r+1), color);// 上

    if ( option & KKUI_DRAW_LOWER_LEFT ||  option & KKUI_DRAW_LOWER_RIGHT )
        _uiSetPoint(x0, (y0+r-1), color);// 下

    if ( option & KKUI_DRAW_UPPER_LEFT ||  option & KKUI_DRAW_LOWER_LEFT )
        _uiSetPoint((x0-r+1), y0, color);// 左
    
    if ( option & KKUI_DRAW_UPPER_RIGHT ||  option & KKUI_DRAW_LOWER_RIGHT )
        _uiSetPoint((x0+r-1), y0, color);// 右
        
    while(b > a)
    {
        b = sqrt(r*r-a*a) + 0.43; // 四舍五入
        if(b - a <= 1 && b >= (int)(sqrt(r*r-(a-1)*(a-1)) + 0.43)) return;
        if(b - a < 1) return;

        if ( option & KKUI_DRAW_UPPER_RIGHT)
        {
            _uiSetPoint((x0+a), (y0-b+1), color);
            if((b-1) != a)
                _uiSetPoint((x0+b-1), (y0-a), color);
        }
        if ( option & KKUI_DRAW_UPPER_LEFT)
        {
            _uiSetPoint((x0-a), (y0-b+1), color);
            if((b-1) != a)
                _uiSetPoint((x0-b+1), (y0-a), color);
        }
        if ( option & KKUI_DRAW_LOWER_RIGHT)
        {
            _uiSetPoint((x0+a), (y0+b-1), color);
            if((b-1) != a)
                _uiSetPoint((x0+b-1), (y0+a), color);
        }
        if ( option & KKUI_DRAW_LOWER_LEFT)
        {
            _uiSetPoint((x0-a), (y0+b-1), color);
            if((b-1) != a)
                _uiSetPoint((x0-b+1), (y0+a), color);
        }
        a ++;
    }
}

void uiDrawRBlock(int x, int y, uint16_t w, uint16_t h, uint16_t r, uint8_t color)
{
		int a, b;
    a = 1;
    b = r;
    while(b > a)
    {
        b = sqrt(r*r-a*a) + 0.43; // 四舍五入
        if(b - a <= 1 && b >= (int)(sqrt(r*r-(a-1)*(a-1)) + 0.43)) break;
        if(b - a < 1) break;

            uiDrawVLine(x+w-r+a, y+r-b, b-a, color);
            uiDrawHLine(x+w-r+a+1, y+r-1-a, b-a-1, color);
			
            uiDrawVLine(x+r-1-a, y+r-b, b-a, color);
            uiDrawHLine(x+r-b, y+r-1-a, b-a-1, color);
			
            uiDrawVLine(x+w-r+a, y+h-r+a, b-a, color);
            uiDrawHLine(x+w-r+a+1, y+h-r+a, b-a-1, color);
			
            uiDrawVLine(x+r-1-a, y+h-r+a, b-a, color);
            uiDrawHLine(x+r-b, y+h-r+a, b-a-1, color);
        a ++;
    }
		
    uiDrawBlock(x+r-1, y, w-2*r+2, r-1, color);
    uiDrawBlock(x+r-1, y+h-r+1, w-2*r+2, r-1, color);
    uiDrawBlock(x, y+r-1, w, h-2*r+2, color);

    // uiDrawBlock(x, y, w, h, 2);
}

void uiDrawRBox(int x, int y, uint16_t w, uint16_t h, uint16_t r, uint8_t color)
{
		int a, b;
    a = 1;
    b = r;
    while(b > a)
    {
        b = sqrt(r*r-a*a) + 0.43; // 四舍五入
        if(b - a <= 1 && b >= (int)(sqrt(r*r-(a-1)*(a-1)) + 0.43)) return;
        if(b - a < 1) return;

            _uiSetPoint((x+w-r+a), (y+r-b), color);
            if((b-1) != a)
                _uiSetPoint((x+w-r+b-1), (y+r-1-a), color);
						
            _uiSetPoint((x+r-1-a), (y+r-b), color);
            if((b-1) != a)
                _uiSetPoint((x+r-b), (y+r-1-a), color);
						
            _uiSetPoint((x+w-r+a), (y+h-r+b-1), color);
            if((b-1) != a)
                _uiSetPoint((x+w-r+b-1), (y+h-r+a), color);
						
            _uiSetPoint((x+r-1-a), (y+h-r+b-1), color);
            if((b-1) != a)
                _uiSetPoint((x+r-b), (y+h-r+a), color);
        a ++;
    }
    uiDrawHLine(x+r-1, y, w-2*r+2, color);
    uiDrawHLine(x+r-1, y+h-1, w-2*r+2, color);
    uiDrawVLine(x, y+r-1, h-2*r+2, color);
    uiDrawVLine(x+w-1, y+r-1, h-2*r+2, color);

    // uiDrawBlock(x, y, w, h, 2);
}

/***************************u8g2********************************/


// 在指定位置显示一个字符,包括部分字符
// x:0~127
// y:0~63
// size1:选择字体 6x8/6x12/8x16/12x24
// mode:0,重叠显示;1,正常显示；2,反色显示
void uiShowChar(int x, int y, char chr, uint8_t size1, uint8_t mode)
{
    uint8_t i, m, temp, size2, chr1;
    int x0 = x, y0 = y;
    uint8_t *char_data;

    if (size1 == 8)
        size2 = 6;
    else
        size2 = (size1 / 8 + ((size1 % 8) ? 1 : 0)) * (size1 / 2); // 得到字体一个字符对应点阵集所占的字节数

    chr1 = chr - ' '; // 计算偏移后的值

    if (size1 == 8)
    {
        char_data = (uint8_t *)ui_asc2_0806[chr1]; // 调用0806字体
    }
    else if (size1 == 12)
    {
        char_data = (uint8_t *)ui_asc2_1206[chr1]; // 调用1206字体
    }
    else if (size1 == 16)
    {
        char_data = (uint8_t *)ui_asc2_1608[chr1]; // 调用1608字体
    }
    else if (size1 == 24)
    {
        char_data = (uint8_t *)ui_asc2_2412[chr1]; // 调用2412字体
    }
    else
        return;

    for (i = 0; i < size2; i++)
    {
        temp = char_data[i];
        if (mode == 0)
        {
            if (size1 != 12)
            {
                for (m = 0; m < 8; m++)
                {
                    if (temp & 0x01)
                        _uiSetPoint(x, y, 1);
                    temp >>= 1;
                    y++;
                }
            }
            else
            {
                if (i < size2 / 2)
                {
                    for (m = 0; m < 8; m++)
                    {
                        if (temp & 0x01)
                            _uiSetPoint(x, y, 1);
                        temp >>= 1;
                        y++;
                    }
                }
                else
                {
                    for (m = 0; m < 4; m++)
                    {
                        if (temp & 0x01)
                            _uiSetPoint(x, y, 1);
                        temp >>= 1;
                        y++;
                    }
                }
            }
        }
        else if (mode == 1)
        {
            if (size1 != 12)
            {
                for (m = 0; m < 8; m++)
                {
                    if (temp & 0x01)
                        _uiSetPoint(x, y, 1);
                    else
                        _uiSetPoint(x, y, 0);
                    temp >>= 1;
                    y++;
                }
            }
            else
            {
                if (i < size2 / 2)
                {
                    for (m = 0; m < 8; m++)
                    {
                        if (temp & 0x01)
                            _uiSetPoint(x, y, 1);
                        else
                            _uiSetPoint(x, y, 0);
                        temp >>= 1;
                        y++;
                    }
                }
                else
                {
                    for (m = 0; m < 4; m++)
                    {
                        if (temp & 0x01)
                            _uiSetPoint(x, y, 1);
                        else
                            _uiSetPoint(x, y, 0);
                        temp >>= 1;
                        y++;
                    }
                }
            }
        }
        else if(mode == 2)
        {
            if (size1 != 12)
            {
                for (m = 0; m < 8; m++)
                {
                    if (temp & 0x01)
                        _uiSetPoint(x, y, 2);
                    temp >>= 1;
                    y++;
                }
            }
            else
            {
                if (i < size2 / 2)
                {
                    for (m = 0; m < 8; m++)
                    {
                        if (temp & 0x01)
                            _uiSetPoint(x, y, 2);
                        temp >>= 1;
                        y++;
                    }
                }
                else
                {
                    for (m = 0; m < 4; m++)
                    {
                        if (temp & 0x01)
                            _uiSetPoint(x, y, 2);
                        temp >>= 1;
                        y++;
                    }
                }
            }
        }            
        x++;
        if ((size1 != 8) && ((x - x0) == size1 / 2))
        {
            x = x0;
            y0 = y0 + 8;
        }
        y = y0;
    }
}

// 显示字符串
// x,y:起点坐标
// size1:字体大小
//*chr:字符串起始地址
// mode:0,重叠显示;1,正常显示；2,反色显示
void uiShowString(int x, int y, char *chr, uint8_t size1, uint8_t mode)
{
    while ((*chr >= ' ') && (*chr <= '~')) // 判断是不是非法字符!
    {
        uiShowChar(x, y, *chr, size1, mode);
        if (size1 == 8)
            x += 6;
        else
            x += size1 / 2;
        chr++;
    }
}

// x,y：起点坐标
// sizex,sizey,图片长宽
// BMP[]：要写入的图片数组
// mode:0,重叠显示;1,正常显示；2,反色显示
void uiShowPicture(int x, int y, int sizex, int sizey, uint8_t BMP[], uint8_t mode)
{
    uint16_t j = 0;
    uint8_t i, n, temp, m;
    int x0 = x, y0 = y;
    sizey = sizey / 8 + ((sizey % 8) ? 1 : 0);
    if (mode == 1)
    {
        for (n = 0; n < sizey; n++)
        {
            for (i = 0; i < sizex; i++)
            {
                temp = BMP[j];
                j++;
                for (m = 0; m < 8; m++)
                {
                    _uiSetPoint(x, y, temp & 0x01);
                    temp >>= 1;
                    y++;
                }
                x++;
                if ((x - x0) == sizex)
                {
                    x = x0;
                    y0 = y0 + 8;
                }
                y = y0;
            }
        }
    }
    else if (mode == 0)
    {
        for (n = 0; n < sizey; n++)
        {
            for (i = 0; i < sizex; i++)
            {
                temp = BMP[j];
                j++;
                for (m = 0; m < 8; m++)
                {
                    if((temp & 0x01))
                        _uiSetPoint(x, y, 1);
                    temp >>= 1;
                    y++;
                }
                x++;
                if ((x - x0) == sizex)
                {
                    x = x0;
                    y0 = y0 + 8;
                }
                y = y0;
            }
        }
    }
    else
    {
        for (n = 0; n < sizey; n++)
        {
            for (i = 0; i < sizex; i++)
            {
                temp = BMP[j];
                j++;
                for (m = 0; m < 8; m++)
                {
                    if (temp & 0x01)
                        _uiSetPoint(x, y, 2);
                    temp >>= 1;
                    y++;
                }
                x++;
                if ((x - x0) == sizex)
                {
                    x = x0;
                    y0 = y0 + 8;
                }
                y = y0;
            }
        }
    }
}

